#include "CThread.h"



namespace lampe{
namespace thread{

bool CThread::isRunning(){
	return thread_isrunning(header);
}

void CThread::stop(){
	if (!isRunning())
		return;
	onStop();
	if (thread_isthis(header)){
		thread_clear(header);
		thread_exit();
	}else{
		thread_stop(header);
		thread_clear(header);
	}
}

bool CThread::cancel(){
	return canceled;
}

void CThread::cancel(bool cancel){
	canceled=cancel;
}

CThread::CThread(){
}

CThread::~CThread(){
    stop();
}

bool CThread::wait(lampe::u32 timeOut,lampe::u32 timeOutStep){
	if (!isRunning())
		return true;
	if (timeOut==0){
		thread_join(header);
		return true;
	}
	s32 time=timeOut;
	while (isRunning() && time>0){
		time-=timeOutStep;
		thread_sleep(timeOutStep);
	}
	return !isRunning();
}

bool CThread::onStart(){
	return true;
}
void CThread::onStop(){
	drop();
}

thread_static_function_of_class(CThread,clientWork,arg){
	((CThread*)arg)->grab();
	if (((CThread*)arg)->onStart()){
		((CThread*)arg)->threadRunning();
		((CThread*)arg)->onStop();
	}
	thread_clear(((CThread*)arg)->header);
	((CThread*)arg)->drop();
	thread_exit();
	return 0;
}

void CThread::start(){
	if (isRunning())
		return;
	grab();
	thread_create(&header,clientWork,(void*)this);
}

bool CThread::abort(lampe::u32 timeOut,lampe::u32 timeOutStep0){
    cancel(true);
    return wait(timeOut,timeOutStep0);
}

/*
#ifdef _IRR_POSIX_LIBLARY_
ThreadHeader thread_id;
#endif

#ifdef _IRR_WINDOWS_
DWORD thread_id;
#endif

extern "C" IRRLICHT_API void IRRCALLCONV setMainThread(){
	thread_id=current_thread();
}

extern "C" IRRLICHT_API bool IRRCALLCONV isMainThread(){
#ifdef _IRR_POSIX_LIBLARY_
	return thread_isthis(thread_id);
#endif
#ifdef _IRR_WINDOWS_
	return thread_id==current_thread();
#endif
}
*/





ThreadID currentID(){
    return current_thread();
}

extern void sleep(lampe::u32 ms){
    thread_sleep(ms);
}

}//namespace thread
}//namespace lampe
